home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 142 / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin / tools / pws / pws011.lzh / ServerCore.c < prev    next >
C/C++ Source or Header  |  2000-02-01  |  8KB  |  322 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <sys/dos.h>
  6. #include <sys/stat.h>
  7. #include <sys/xglob.h>
  8.  
  9. #include <network.h>
  10. #include <socket.h>
  11. #include "PersonalWS.h"
  12. #include "ServerCore.h"
  13.  
  14.  
  15. static int sock80, temp_sock = -1;
  16.  
  17.  
  18. typedef struct {
  19.     char *content_type;
  20.     char *ext_type;
  21. } TYPE_TABLE;
  22.  
  23. TYPE_TABLE type_table[] =
  24. {
  25.     "text/html", "HTM",
  26.     "text/html", "HTML",
  27.     "text/html", "CGI",
  28.     "text/plain", "TXT",
  29.     "text/plain", "DOC",
  30.     "image/gif", "GIF",
  31.     "image/jpeg", "JPG",
  32.     "image/jpeg", "JPEG",
  33.     "image/png", "PNG",
  34.     "image/bmp", "BMP",
  35.     "application/zip", "ZIP",
  36.     "application/x-lzh", "LZH",
  37.     "application/x-gzip", "TGZ",
  38.     "application/pdf", "PDF",
  39.  
  40.     NULL, NULL
  41. };
  42.  
  43.  
  44. /* ソケットをオープンする(常駐解除に使うだけ) */
  45. int OpenSock (char *hostname, int port)
  46. {
  47.  
  48.     int sock;
  49.     struct hostent *h;
  50.     struct sockaddr_in addr;
  51.  
  52.     /* ソケットを作成する */
  53.     sock = socket (AF_INET, SOCK_STREAM, 0);
  54.     if (sock < 0) {
  55.         printf ("    エラー : ソケットが作成できませんでした\n");
  56.         return (-1);
  57.     }
  58.     memset (&addr, 0, sizeof (addr));    /* 0 で埋める */
  59.  
  60.     addr.sin_family = AF_INET;    /* INETドメインを指定 */
  61.     addr.sin_port = htons (port);    /* ポート番号 */
  62.     /* ホスト名(www.xxx.co.jp) を IP アドレス(int)に変換 */
  63.     h = gethostbyname (hostname);
  64.     if (h == NULL) {
  65.         printf ("    エラー : ドメイン名がみつかりません\n");
  66.         return (-1);
  67.     }
  68.     addr.sin_addr.s_addr = *(long *) h->h_addr;
  69.  
  70.     /* 相手先に接続する */
  71.     verbose_printf ("    接続中...\n");
  72.  
  73.     if (connect (sock, (char *) &addr, sizeof (addr)) < 0) {
  74.         printf ("    エラー : 接続に失敗しました\n");
  75.         return (-1);
  76.     }
  77.     return (sock);
  78. }
  79.  
  80.  
  81. /* 指定されたソケットからメッセージを受け取る */
  82. int ReceiveMessage (int sock)
  83. {
  84.     char temp_str[1024];
  85.  
  86.     verbose_printf ("受信待ち...\n");
  87.     while (!socklen (sock, 0));    /* 受信待ち */
  88.     do {
  89.         recvline (sock, temp_str, 1024);    /* 受信 */
  90.         verbose_printf ("受信 > %s\n", temp_str);
  91.     } while (socklen (sock, 0) > 0);
  92.  
  93.     return (0);
  94. }
  95.  
  96.  
  97. /* 指定されたソケットにコマンドを送る */
  98. int SendCommand (int sock, char *cmd)
  99. {
  100.     verbose_printf ("送信 > %s\n", cmd);
  101.     write_s (sock, cmd, strlen (cmd));    /* 送信 */
  102.     while (!socklen (sock, 1));    /* 送信完了待ち */
  103.     ReceiveMessage (sock);
  104.     return (0);
  105. }
  106.  
  107.  
  108. /* Passive 用ソケットをオープンする */
  109. int OpenPassiveSock (int port)
  110. {
  111.     int sock;
  112.     struct sockaddr_in addr;
  113.  
  114.     /* ソケットを作成する */
  115.     sock = socket (AF_INET, SOCK_STREAM, 0);
  116.     if (sock < 0) {
  117.         printf ("    エラー : ソケットが作成できませんでした\n");
  118.         return (-1);
  119.     }
  120.     memset (&addr, 0, sizeof (addr));    /* 0 で埋める */
  121.  
  122.     addr.sin_family = AF_INET;    /* INETドメインを指定 */
  123.     addr.sin_port = htons (port);    /* ポート番号 */
  124. #if    0
  125.     addr.sin_addr.s_addr = INADDR_ANY;
  126. #endif
  127.     addr.sin_addr.s_addr = htonl (0);    /* INADDR_ANY:0 */
  128.     /* 相手先に接続する */
  129.     if (bind (sock, (char *) &addr, sizeof (addr)) < 0) {
  130.         printf ("    エラー : 接続に失敗しました\n");
  131.         return (-1);
  132.     }
  133.     if (listen (sock, 1) < 0) {
  134.         printf ("    エラー : listen でエラーが発生しました\n");
  135.         return (-1);
  136.     }
  137.     return (sock);
  138. }
  139.  
  140.  
  141.  
  142. /* 接続されるのを待つ */
  143. int AcceptSock (int sock)
  144. {
  145.     struct sockaddr_in from;
  146.     int temp_sock;
  147.  
  148.     int len = sizeof (from);
  149.     temp_sock = accept (sock, (char *) &from, &len);
  150.     if (temp_sock < 0) {
  151.         printf ("    エラー : accept でエラーが発生しました\n");
  152.         return (-1);
  153.     }
  154.     return (temp_sock);
  155. }
  156.  
  157.  
  158. void CloseSock (int sock)
  159. {
  160.     if (sock > 0)
  161.         close_s (sock);
  162. }
  163.  
  164.  
  165. int ServerInit (void)
  166. {
  167.     if (_get_version () < 0) {
  168.         printf ("(h)inetd.x が常駐していません\n");
  169.         return (-1);
  170.     }
  171.     sock80 = OpenPassiveSock (80);
  172.     if (sock80 < 0)
  173.         return (-1);
  174.     return (0);
  175. }
  176.  
  177.  
  178. int ServerMain (void)
  179. {
  180.     char temp_str[1024];
  181.     char method[64], url[1024], version[64];
  182.     FILE *fp;
  183.     char *content_type = "application/octet-stream";    /* 謎の拡張子の場合コレになる */
  184.     char *p = url;
  185.     char *ext = NULL;
  186.     TYPE_TABLE *t;
  187.  
  188.     verbose_printf ("接続を待っています\n");
  189.     temp_sock = AcceptSock (sock80);
  190.     if (temp_sock < 0)
  191.         return (-1);
  192.     sockmode (temp_sock, SOCK_ASCII);
  193.     seteol (temp_sock, "\r\n");
  194.     verbose_printf ("接続されました\n");
  195.  
  196.     while (recvline (temp_sock, temp_str, sizeof (temp_str)) < 0);
  197.     sscanf (temp_str, "%s %s %s", method, url, version);
  198.     verbose_printf ("    ヘッダ > %s", temp_str);
  199.  
  200. #if    0
  201.     while (recvline (temp_sock, temp_str, sizeof (temp_str)) > 2) {
  202.         verbose_printf ("    ヘッダ > %s", temp_str);
  203.     }
  204. #endif
  205.     do {
  206.         if (recvline (temp_sock, temp_str, sizeof (temp_str)) < 0)
  207.             break;
  208.         verbose_printf ("    ヘッダ > %s", temp_str);
  209.     } while (*temp_str != '\n');
  210.  
  211.  
  212.     /* 終了文字列のチェック */
  213.     sprintf (temp_str, "/%s", quit_str);
  214.     if (!strnicmp (url, temp_str, strlen (temp_str))) {
  215.         close_s (temp_sock);
  216.         temp_sock = -1;
  217.         return (-1);    /* 常駐解除 */
  218.     }
  219.     if ((!strcmp (method, "HEAD")) || (!strcmp (method, "GET"))) {
  220.         struct stat sb;
  221.  
  222.         strcpy (temp_str, base_dir);
  223.         _dellastsep (temp_str);
  224.         strcat (temp_str, url);
  225.  
  226.         if ((fp = fopen (temp_str, "rb")) != NULL) {
  227.             /* ローカルファイルの拡張子から content_type を得る */
  228.             while (*p) {
  229.                 if (*p++ == '.')
  230.                     ext = p;
  231.             }
  232.             if (ext) {
  233.                 t = type_table;
  234.                 do {
  235.                     if (!stricmp (ext, t->ext_type)) {
  236.                         content_type = t->content_type;
  237.                         break;
  238.                     }
  239.                 } while ((++t)->ext_type != NULL);
  240.             }
  241.             stat (temp_str, &sb);
  242.             verbose_printf ("    %s を送信します\n", temp_str);
  243.  
  244.             strcpy (temp_str, "HTTP/1.0 200 OK\r\n");
  245.             write_s (temp_sock, temp_str, strlen (temp_str));
  246.             sprintf (temp_str, "Content-Type: %s\r\n", content_type);
  247.             write_s (temp_sock, temp_str, strlen (temp_str));
  248.             sprintf (temp_str, "Content-Length: %d\r\n", sb.st_size);
  249.             write_s (temp_sock, temp_str, strlen (temp_str));
  250.             strftime (temp_str, 96, "Last-Modified: %a, %d %b %Y %T GMT\r\n", gmtime (&sb.st_ctime));
  251.             write_s (temp_sock, temp_str, strlen (temp_str));
  252.             strcpy (temp_str, "\r\n");    /* ヘッダの終了 */
  253.             write_s (temp_sock, temp_str, strlen (temp_str));
  254.  
  255. #if 0
  256.             /* これじゃなんか動かん */
  257.             while (!feof (fp))
  258.                 write_s (temp_sock, temp_str, fread (temp_str, sizeof (char), sizeof (temp_str), fp));
  259. #endif
  260.             if (!strcmp (method, "GET")) {
  261.                 int r1, r2 = 0;
  262.                 sockmode (temp_sock, SOCK_BINARY);
  263.  
  264.                 for (;;) {
  265.                     r1 = fread (temp_str, sizeof (char), sizeof (temp_str), fp);
  266.                     if ((r2 + r1) > sb.st_size) {
  267.                         r1 = sb.st_size - r2;
  268.                         write_s (temp_sock, temp_str, r1);
  269.                         break;
  270.                     }
  271.                     r2 += r1;
  272.                     write_s (temp_sock, temp_str, r1);
  273.                     if (feof (fp))
  274.                         break;
  275.                 }
  276.             }
  277.             fclose (fp);
  278.         } else {
  279.             strcpy (temp_str, "HTTP/1.0 404 Not Found\r\n");
  280.             write_s (temp_sock, temp_str, strlen (temp_str));
  281.  
  282.             if (!strcmp (method, "GET")) {
  283.                 strcpy (temp_str, "Content-Type: text/html\r\n");
  284.                 write_s (temp_sock, temp_str, strlen (temp_str));
  285.                 strcpy (temp_str, "\r\n");    /* ヘッダの終了 */
  286.                 write_s (temp_sock, temp_str, strlen (temp_str));
  287.  
  288.                 strcpy (temp_str,
  289.                     "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>"
  290.                     "<BODY><H1>404 Not Found</H1>\r\n"
  291.                     "</BODY></HTML>\r\n"
  292.                     );
  293.                 write_s (temp_sock, temp_str, strlen (temp_str));
  294.             } else {
  295.                 strcpy (temp_str, "\r\n");    /* ヘッダの終了 */
  296.                 write_s (temp_sock, temp_str, strlen (temp_str));
  297.             }
  298.         }
  299.     } else {
  300.         /* HEAD/GET 以外の処理 */
  301.     }
  302.     while (!socklen (temp_sock, 1));    /* 送信完了待ち */
  303.     shutdown (temp_sock, 0);    /* 受信したデータを受け取らず,すべて廃棄する */
  304.     shutdown (temp_sock, 1);    /* TCP FINを送信し,データの送出をやめる */
  305.     //shutdown (temp_sock, 2);      /* connection を abortする */
  306.     close_s (temp_sock);
  307.     temp_sock = -1;
  308.  
  309.     return (0);
  310. }
  311.  
  312.  
  313.  
  314. int ServerTini (void)
  315. {
  316.     if (sock80 > 0)
  317.         close_s (sock80);
  318.     if (temp_sock > 0)
  319.         close_s (temp_sock);
  320.     return (0);
  321. }
  322.